home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 008a / intr26b.zip / INT2HLP.BAT < prev    next >
DOS Batch File  |  1991-04-18  |  13KB  |  500 lines

  1. @REM=("
  2. @perl -w %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
  3. @end ") if 0 ;
  4. #
  5. # Create a quickhelp file from the PC interrupt list.
  6. # By Diomidis Spinellis <dds@cc.ic.ac.uk>.
  7. #
  8. # You will need the Microsoft helpmake utility, a sort that takes the -f (fold)
  9. # option, around 9 hours of 20MHz 386 CPU time and around 4 MB of disk space.
  10. # Put all the interrupt list distribution files in one directory and run the
  11. # program.
  12. #
  13. # (C) Copyright 1991 Diomidis Spinellis.  All rights reserved.
  14. # Permission to use and distribute this file without modification is given.
  15. #
  16.  
  17. $labelnum = 0;
  18. # int.byf - Interrupts by Function (Tree Internal Nodes)
  19. &maketop_by_function();
  20. &makecont(0, "Interrupts by Function", "int.byfunc", "int.hlp");
  21. &merge_out('int.byf');
  22. # int.byv - Interrupts by Value (Tree Internal Nodes)
  23. &maketop_by_value();
  24. &makecont(0, "Interrupts by Value", "int.byval", "int.hlp");
  25. &merge_out('int.byv');
  26. # int.bot - Interrupt List Interrupts (Tree Terminal Nodes)
  27. &summary('int.byv', 'sum.byv');
  28. &summary('int.byf', 'sum.byf');
  29. &makebottom();
  30. &unlink_intermediate();
  31. unlink('interrup.lst');    # To make room
  32. # int.idx - Interrupt List Index
  33. &makeindex();
  34. # int.fil - Interrupt List Auxiliary Files
  35. unlink('int.fil');
  36. &incfile('int.mem', 'Memory List', 'memory.lst');
  37. &incfile('int.pri', 'Interrupt Primer', 'interrup.pri');
  38. &incfile('int.ack', 'Distribution, Abbreviations and Acknowledgements', 'interrup.1st');
  39. # int.toc - Interupt List Table of Contents
  40. &maketoc();
  41. exec('helpmake', '/T', '/e', '/W100', '/oint.hlp', '/V', 'int.toc', 'int.byv', 'int.byf', 'int.bot', 'int.idx', 'int.fil');
  42.  
  43. # Create a contents file.  Level is the recursive level, topic the
  44. # header to use, context the unique identifier for this topic and
  45. # up the identifier of the parent topic.
  46. # Works by scanning the input of the current level line by line and
  47. # identifying topics.  If the topic is unique it is output on a list
  48. # else the topic is output on the list with a pointer to another list
  49. # and the function is called recursively.
  50. sub makecont
  51. {
  52.     local($level, $topic, $context, $up) = @_;
  53.     local($IN, $OUT);
  54.     local($l, $prev, $part, $ref, $tmp);
  55.  
  56.     $IN = "IN$level";
  57.     $OUT = "OUT$level";
  58.     open($IN, "sort in$level|") || die;
  59.     open($OUT, ">>out$level") || die;
  60.  
  61.     print "makecont($level, [$topic], [$context], [$up])\n";
  62.     print $OUT ".context $context\n";
  63.     print $OUT ".freeze 3\n";
  64.     print $OUT ".topic $topic\n";
  65.     print $OUT "                                             \\i\021\\p\\aUp\\v${up}\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  66.     print $OUT "\304" x 75 . "\n\n";
  67.     while (<$IN>) {
  68.         chop;
  69.         print "$level: Read [$_]\n";
  70.         $part = (split(/ \- /))[0];
  71.         if ($part =~ /^`/) {
  72.             $part =~ s/`//;
  73.         } else {
  74.             $part =~ s/`.*//;
  75.         }
  76.         next if ($part eq $prev);
  77.         $ref = (split(/`/))[1];
  78.         print "part = [$part]\n";
  79.         if (&count($part, "in$level") <= 1) {
  80.             if ($ref eq '') {
  81.                 print $OUT "\t\\a$part\\v$part\\v\n";
  82.             } else {
  83.                 print $OUT "\t\\a$part\\v$ref\\v\n";
  84.             }
  85.         } else {
  86.             $u = &newlabel();
  87.             print $OUT "\t\\a$part\\v$u\\v\n";
  88.             $l = $level + 1;
  89.             ©match($part, "in$level", "in$l");
  90.             $tmp = $context;
  91.             &makecont($l, $part, $u, $tmp);
  92.         }
  93.         $prev = $part;
  94.     }
  95.     print $OUT ' ' x 35 . "-\04-\n";
  96.     close($IN);
  97.     close($OUT);
  98. }
  99.  
  100. # Return number of lines matching string
  101. sub count
  102. {
  103.     local($string, $file) = @_;
  104.  
  105.     $string =~ s/(\W)/\\$1/g;
  106.     open (CIN, $file) || die;
  107.     $count = 0;
  108.     while (<CIN>) {
  109.         $count++ if (/^$string(( - )|`)/);
  110.     }
  111.     print "count($string) = $count\n";
  112.     close(CIN);
  113.     return $count;
  114. }
  115.  
  116. # Copy lines that match string from $in to $out removing string
  117. sub copymatch
  118. {
  119.     local($string, $in, $out) = @_;
  120.  
  121.     $string =~ s/(\W)/\\$1/g;
  122.     open(CIN, $in) || die;
  123.     open(COUT, ">$out") || die;
  124.     while (<CIN>) {
  125.         if (/^$string(( - )|`)/) {
  126.             s/^$string[-\s`]*//;
  127.             print COUT;
  128.         }
  129.     }
  130.     close(CIN);
  131.     close(COUT);
  132. }
  133.  
  134. # Open the interrupt list and create a file with one line for each
  135. # interrupt.  The line consists of the interrupt description followed
  136. # by a backtick and the interrupt number.
  137. sub maketop_by_function
  138. {
  139.     &unlink_out();
  140.     open(IN, "interrup.lst") || die;
  141.     open(OUT, ">in0") || die;
  142.     while (<IN>) {
  143.         if (/^--------/) {
  144.             chop;
  145.             $int = $_;
  146.             $int =~ s/-+//g;
  147.             if ($last eq $int) {
  148.                 $int .= $letter++;
  149.             } else {
  150.                 $letter = 'a';
  151.                 $last = $int;
  152.             }
  153.         }
  154.         if (/^INT /) {
  155.             chop;
  156.             $line = $_;
  157.             $line =~ s/^INT [^-]*- //;
  158.             $line =~ s/\\/\\\\/g;
  159.             print OUT "$line\`$int\n";
  160.         }
  161.     }
  162.     close(IN);
  163.     close(OUT);
  164. }
  165.  
  166. # Return a unique new label
  167. sub newlabel
  168. {
  169.     return "\@IL" . $labelnum++;
  170. }
  171.  
  172. # Unlink all output files
  173. sub unlink_out
  174. {
  175.     for ($i = 0; $i < 10; $i++) {
  176.         unlink("out$i");
  177.     }
  178. }
  179.  
  180. # Unlink all intermediate files
  181. sub unlink_intermediate
  182. {
  183.     for ($i = 0; $i < 10; $i++) {
  184.         unlink("out$i");
  185.         unlink("in$i");
  186.     }
  187.     unlink('sum.byf');
  188.     unlink('sum.byv');
  189. }
  190.  
  191. # Merge the output files into int.byf
  192. sub merge_out
  193. {
  194.     local($outname) = @_;
  195.  
  196.     open(OUT, ">$outname");
  197.     for ($i = 0; $i < 10; $i++) {
  198.         if (open(IN, "out$i")) {
  199.             while (<IN>) {
  200.                 print OUT;
  201.             }
  202.             close(IN);
  203.         }
  204.     }
  205.     close(OUT);
  206.     &unlink_out();
  207. }
  208.  
  209. # Open the interrupt list and create a file with one line for each
  210. # interrupt.  The line consists of the interrupt identifications
  211. # (number and register values) followed by the unique interrupt identifier
  212. sub maketop_by_value
  213. {
  214.     &unlink_out();
  215.     open(IN, "interrup.lst") || die;
  216.     open(OUT, ">in0") || die;
  217.     while (<IN>) {
  218.         if (/^----------[0-9A-F]/) {
  219.             chop;
  220.             $int = $_;
  221.             $int =~ s/-+//g;
  222.             if ($last eq $int) {
  223.                 $int .= $letter++;
  224.             } else {
  225.                 $letter = 'a';
  226.                 $last = $int;
  227.             }
  228.             $_ =~ /^----------(..)(..)(..)(..)(....)/;
  229.             $num = $1;    # Interrupt number
  230.             $ah = $2;    # Register AH
  231.             $al = $3;    # Register AL
  232.             $rn = $4;    # Other register name
  233.             $rv = $5;    # Other register value (8 or 16 bit)
  234.             $rv =~ s/-//g;
  235.             print OUT "INT $num";
  236.             print OUT " - AH = $ah" if ($ah ne '--');
  237.             print OUT " - AL = $al" if ($al ne '--');
  238.             print OUT " - $rn = $rv" if ($rn ne '--');
  239.             print OUT "`$int\n";
  240.         }
  241.     }
  242.     close(IN);
  243.     close(OUT);
  244. }
  245.  
  246. # Create the bottom nodes of the file
  247. # Each node contains a navigation line for going upwards by value or function
  248. # Try to create seens for the SeeAlso lines
  249. sub makebottom
  250. {
  251.     open(IN, "interrup.lst") || die;
  252.     open(OUT, ">int.bot") || die;
  253.     print OUT ".context int.intro\n";
  254.     print OUT ".freeze 3\n";
  255.     print OUT ".topic Interrupt List\n";
  256.     print OUT "                                             \\i\021\\p\\aUp\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  257.     print OUT "\304" x 75 . "\n\n";
  258.     while (<IN>) {
  259.         chop;
  260.         s/\\/\\\\/g;
  261.         if (/^----------[0-9A-F]/) {
  262.             $int = $_;
  263.             $int =~ s/-+//g;
  264.             if ($last eq $int) {
  265.                 $int .= $letter++;
  266.             } else {
  267.                 $letter = 'a';
  268.                 $last = $int;
  269.             }
  270.             $_ =~ /^----------(..)(..)(..)(..)(....)/;
  271.             $num = $1;    # Interrupt number
  272.         } elsif (/^INT /) {
  273.             $line = $_;
  274.             print "$line\n";
  275.             print OUT ' ' x 35 . "-\04-\n";
  276.             print OUT ".context $int\n";
  277.             print OUT ".freeze 4\n";
  278.             print OUT ".topic $line\n";
  279.             $upf = &parent('sum.byf', $int);
  280.             $upv = &parent('sum.byv', $int);
  281.             print OUT "                         \\i\021\\p\\aUp Function\\v${upf}\\v\\i\020\\p \\i\021\\p\\aUp Value\\v${upv}\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  282.             print OUT "\304" x 75 . "\n";
  283.             print OUT "\\b$line\\p\n\n";
  284.         } elsif (/^SeeAlso: (.*)$/) {
  285.             print OUT '\bSeeAlso:\p ';
  286.             @back = @list = split(/, */, $1);
  287.             for ($i = 0; $i <= $#list; $i++) {
  288.                 $list[$i] =~ s/"[^"]*"//g;
  289.                 $list[$i] =~ s/A[HX]//g;
  290.                 $list[$i] =~ s/[\/h=]//g;
  291.                 if ($list[$i] =~ /^INT (..)/) {
  292.                     $num = $1;
  293.                     $list[$i] =~ s/^INT //;
  294.                 } else {
  295.                     $list[$i] =~ s/^/$num/;
  296.                 }
  297.                 if ($cont = &intcontext($list[$i])) {
  298.                     print OUT "\\i\021\\p\\a$back[$i]\\i\020\\p\\v$cont\\v";
  299.                 } elsif (&exists($list[$i])) {
  300.                     print OUT "\\i\021\\p\\a$back[$i]\\i\020\\p\\v$list[$i]\\v";
  301.                 } else {
  302.                     print OUT "$back[$i]";
  303.                 }
  304.                 print OUT ', ' if ($i < $#list);
  305.             }
  306.             print OUT "\n";
  307.         } elsif (/^(\w+:)(.*)$/) {
  308.             print OUT "\\b$1\\p$2\n";
  309.         } else {
  310.             print OUT;
  311.             print OUT "\n";
  312.         }
  313.     }
  314.     print OUT ' ' x 35 . "-\04-\n";
  315.     close(IN);
  316.     close(OUT);
  317. }
  318.  
  319. # Reding $in create a $out file containing each context and its parent
  320. # context.
  321. sub summary
  322. {
  323.     local($in, $out) = @_;
  324.  
  325.     open(IN, $in) || die;
  326.     open(OUT, ">$out") || die;
  327.     while (<IN>) {
  328.         chop;
  329.         next if (/\\i\021\\p/);
  330.         if (/^\.context (.*)$/) {
  331.             $context = $1;
  332.         }
  333.         if (/\\v([^I][^\\]+)/) {
  334.             print OUT "$1`$context\n";
  335.         }
  336.     }
  337. }
  338.  
  339. # Return the parent of node $val in file $in
  340. sub parent
  341. {
  342.     local ($in, $val) = @_;
  343.  
  344.     open (SUM, $in) || die;
  345.     while (<SUM>) {
  346.         chop;
  347.         if (/^$val`(.*)$/) {
  348.             close(SUM);
  349.             return $1;
  350.         }
  351.     }
  352.     print STDERR "$val has not parent node!\n";
  353.     close(SUM);
  354.     return 'int.hlp';
  355. }
  356.  
  357. # Return true if a bottom node $val exists as a context
  358. sub exists
  359. {
  360.     local ($val) = @_;
  361.  
  362.     open (EX, 'sum.byf') || die;
  363.     while (<EX>) {
  364.         chop;
  365.         if (/^$val`/) {
  366.             close(SUM);
  367.             return 1;
  368.         }
  369.     }
  370.     print STDERR "$val does not exist!\n";
  371.     close(SUM);
  372.     return 0;
  373. }
  374.  
  375. # Given a two digit interrupt number return the correct context
  376. # Works by searching the first 300 lines of int.byv.  Do not change
  377. # its format without checking this function.
  378. sub intcontext
  379. {
  380.     local($int) = @_;
  381.  
  382.     if ($int !~ /^[0-9][A-F][0-9][A-F]$/) {
  383.         return undef;
  384.     }
  385.     open(INC, 'int.byv') || die;
  386.     $i = 0;
  387.     while (<INC> && $i < 300) {
  388.         if (/\\aINT $int\\v([^\\]+)\\v$/) {
  389.             close(INC);
  390.             return $1;
  391.         }
  392.         $i++;
  393.     }
  394.     close(INC);
  395.     print STDERR "Unable to locate interrupt $int\n";
  396.     return undef;
  397. }
  398.  
  399. # Make a simple index by concatenating all the int.byf lines and sorting them
  400. # by character.
  401. sub makeindex
  402. {
  403.     open(IN, 'sort -f int.byf|');
  404.     open(OUT, '>int.idx');
  405.     undef $prev;
  406.     while (<IN>) {
  407.         if (/^\t\\a(.)/) {
  408.             $letter = $1;
  409.             $letter =~ tr/[a-z]/[A-Z]/;
  410.             if ($letter ne $prev) {
  411.                 print OUT ' ' x 35 . "-\04-\n" if ($prev);
  412.                 print OUT ".context \@IL.$letter\n";
  413.                 print OUT ".freeze 3\n";
  414.                 print OUT ".topic Index $letter\n";
  415.                 print OUT "                                             \\i\021\\p\\aUp\\vint.idx\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  416.                 print OUT "\304" x 75 . "\n\n";
  417.                 $all .= $letter;
  418.                 $prev = $letter;
  419.             }
  420.             print OUT;
  421.         }
  422.     }
  423.     close(IN);
  424.     print OUT ' ' x 35 . "-\04-\n";
  425.     print OUT ".context int.idx\n";
  426.     print OUT ".context h.idx\n";
  427.     print OUT ".freeze 3\n";
  428.     print OUT ".topic Index\n";
  429.     print OUT "                                             \\i\021\\p\\aUp\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  430.     print OUT "\304" x 75 . "\n\n";
  431.     for ($i = 0; $i < length($all); $i++) {
  432.         $l = substr($all, $i, 1);
  433.         print OUT "\\a\t\\i\021\\p$l\\i\020\\p\\v\@IL.$l\\v\n";
  434.     }
  435.     print OUT ' ' x 35 . "-\04-\n";
  436.     close(OUT);
  437. }
  438.  
  439. # Include a file with given context, topic and filename to the file int.fil
  440. sub incfile
  441. {
  442.     local($context, $topic, $name) = @_;
  443.  
  444.     open(OUT, '>>int.fil');
  445.     open(IN, "$name") || die;
  446.     print OUT ".context $context\n";
  447.     print OUT ".freeze 3\n";
  448.     print OUT ".topic $topic\n";
  449.     print OUT "                                             \\i\021\\p\\aUp\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  450.     print OUT "\304" x 75 . "\n\n";
  451.     while (<IN>) {
  452.         s/\\/\\\\/g;
  453.         print OUT;
  454.     }
  455.     print OUT ' ' x 35 . "-\04-\n";
  456.     close(OUT);
  457. }
  458.  
  459. # Create the table of contents file
  460. sub maketoc
  461. {
  462.     open(OUT, '>int.toc') || die;
  463.     print OUT 
  464. ".context Interrupt List
  465. .context int.hlp
  466. .context int
  467. .context interrupt list
  468. .context h.contents
  469. .context h.pg1
  470. .context contents
  471. .freeze 3
  472. .topic The Interrupt List
  473. \t\t\t\\bThe PC Interrupt List\\p
  474. \t
  475.  
  476. \t\\a\\i\021\\pIntroduction\\vint.intro\\v\\i\020\\p
  477.  
  478. \t\\a\\i\021\\pInterrupts by Value\\vint.byval\\v\\i\020\\p
  479.  
  480. \t\\a\\i\021\\pInterrupts by Function\\vint.byfunc\\v\\i\020\\p
  481.  
  482. \t\\a\\i\021\\pMemory List\\vint.mem\\v\\i\020\\p
  483.  
  484. \t\\a\\i\021\\pInterrupt Primer\\vint.pri\\v\\i\020\\p
  485.  
  486. \t\\a\\i\021\\pIndex\\vint.idx\\v\\i\020\\p
  487.  
  488. \t\\a\\i\021\\pDistribution, Abbreviations and Acknowledgements\\vint.ack\\v\\i\020\\p
  489.  
  490.  
  491. Compilation Copyright (c) 1989, 1990, 1991 Ralf Brown
  492. Helpmake conversion Copyright (c) 1991 Diomidis Spinellis
  493.  
  494.                                    -\04-
  495. .context List Categories
  496. Interrupt List
  497. ";
  498.     close(OUT);
  499. }
  500.